import {
  CLASSES,
  NUM_CLASSES,
  NUM_CHANNELS,
  NUM_DATASET_ELEMENTS,
  IMAGE_SIZE,
  IMAGE_WIDTH,
  IMAGE_HEIGHT,
  IMAGE_WIDTH_2,
  IMAGE_HEIGHT_2,
  font,
  saveDir,
  imagesFileName,
  labelsFileName
} from "./OCRDatasetConstants";
import { createFile } from "@/renderer/api/messageAPI";

// 生成未编码的图片像素信息的二进制文件
export async function createImagesDataset() {
  const canvas = document.createElement("canvas");
  const datasetBytesBuffer = new ArrayBuffer(
    NUM_DATASET_ELEMENTS * IMAGE_SIZE * NUM_CHANNELS * 1
  ); // NUM_DATASET_ELEMENTS * IMAGE_SIZE * byte * NUM_CHANNELS； Uint8Array 1字节，Uint16Array 2字节， Float32Array 4字节
  const datasetTypedArray = new Uint8Array(
    datasetBytesBuffer,
    0,
    NUM_DATASET_ELEMENTS * IMAGE_SIZE * NUM_CHANNELS
  );
  const ctx = canvas.getContext("2d");

  canvas.width = IMAGE_WIDTH;
  canvas.height = IMAGE_HEIGHT;

  function clear() {
    ctx.fillStyle = "#000";
    ctx.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
  }

  function write(str, font) {
    ctx.fillStyle = "#fff";
    ctx.font = font;
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText(str, IMAGE_WIDTH_2, IMAGE_HEIGHT_2);
  }

  for (const i in font) {
    const ft = font[i];

    for (const j in CLASSES as any) {
      clear();
      write(CLASSES[j], ft);

      const data = ctx.getImageData(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT).data;

      datasetTypedArray.set(
        data,
        (Number(i) * NUM_CLASSES + Number(j)) * IMAGE_SIZE * NUM_CHANNELS
      );
    }
  }

  await createFile(saveDir + imagesFileName, datasetTypedArray);

  return datasetTypedArray;
}

export async function createLabelsDataset() {
  const indices = font.reduce((pre) => {
    return pre.concat(
      Array(NUM_CLASSES)
        .fill(0)
        .map((v, i) => i)
    );
  }, []);

  const typedArray = new Uint32Array(indices);
  // 存储标签索引数组
  await createFile(saveDir + labelsFileName, typedArray);

  return typedArray;
}
// canvas最大的画布尺寸 Chrome 最大高度：65,535; 最大宽度：65,535; 最大面积：268,435,456
export function showOCRImages(typedArray) {
  const uint8ClampedArray = new Uint8ClampedArray(typedArray);

  const length = IMAGE_SIZE * NUM_CHANNELS;

  const cols = 20;
  const rows = Math.min(
    Math.ceil(NUM_DATASET_ELEMENTS / cols),
    65535 / (IMAGE_HEIGHT + 1)
  );
  const space = 1;

  const canvas = document.createElement("canvas");
  canvas.width = (IMAGE_WIDTH + space) * cols;
  canvas.height = (IMAGE_HEIGHT + space) * rows;
  const ctx = canvas.getContext("2d");

  for (let i = 0; i < rows; i++) {
    for (let j = 0; j < cols; j++) {
      const start = length * (i * cols + j);

      const end = start + length;
      const tArr = uint8ClampedArray.slice(start, end);

      if (tArr.length == 0) continue;

      const imgData = new ImageData(tArr, IMAGE_WIDTH, IMAGE_HEIGHT);
      ctx.putImageData(
        imgData,
        j * (IMAGE_WIDTH + space),
        i * (IMAGE_HEIGHT + space)
      );
    }
  }

  const img = document.createElement("img");

  canvas.toBlob((blob) => {
    const url = URL.createObjectURL(blob);

    img.onload = () => {
      img.width = img.naturalWidth;
      img.height = img.naturalHeight;

      URL.revokeObjectURL(url);
    };

    img.src = url;
  });

  return img;
}
